package com.cssw.fyzb.busi.service.video;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.busi.config.EventClient;
import com.cssw.fyzb.busi.config.TpsClient;
import com.cssw.fyzb.busi.convert.Converter;
import com.cssw.fyzb.busi.model.tps.Address;
import com.cssw.fyzb.busi.model.tps.UploadSigVo;
import com.cssw.fyzb.busi.model.tps.UploadVod;
import com.cssw.fyzb.busi.util.TimeUtil;
import com.cssw.fyzb.core.dao.user.UserAttentionDao;
import com.cssw.fyzb.core.dao.user.UserDao;
import com.cssw.fyzb.core.model.vo.video.*;
import com.cssw.fyzb.busi.util.Const;
import com.cssw.fyzb.busi.util.GeoUtil;
import com.cssw.fyzb.busi.util.UuidUtil;
import com.cssw.fyzb.core.dao.acct.AcctDao;
import com.cssw.fyzb.core.dao.user.UserExtDao;
import com.cssw.fyzb.core.dao.user.UserRelDao;
import com.cssw.fyzb.core.dao.video.*;
import com.cssw.fyzb.core.eao.acct.AcctLogEao;
import com.cssw.fyzb.core.eao.video.VideoEao;
import com.cssw.fyzb.core.eao.video.VideoLikeEao;
import com.cssw.fyzb.core.mao.user.UserFollowMao;
import com.cssw.fyzb.core.mao.user.UserMao;
import com.cssw.fyzb.core.mao.video.UserVideoMao;
import com.cssw.fyzb.core.mao.video.VideoStatMao;
import com.cssw.fyzb.core.mao.video.VideoViewStatMao;
import com.cssw.fyzb.core.model.dodb.*;
import com.cssw.fyzb.core.model.eos.VideoEo;
import com.cssw.fyzb.core.model.eos.VideoLikeEo;
import com.cssw.fyzb.core.model.mos.UserMo;
import com.cssw.fyzb.core.model.mos.VideoStatMo;
import com.cssw.fyzb.core.model.mos.VideoViewStatMo;
import com.cssw.fyzb.core.util.AesUtil;
import com.cssw.fyzb.core.util.BizUtil;
import com.cssw.fyzb.core.util.DateUtil;
import com.cssw.fyzb.core.util.StringUtil;
import com.ydn.dbframe.plugin.activerecord.Db;
import com.ydn.dbframe.plugin.activerecord.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Feng Chen
 */
@Service
public class VideoServiceImpl implements VideoService {

    @Autowired
    private UserVideoDao videoDao;

    @Autowired
    private VideoEao videoEao;

    @Autowired
    private UserRelDao userRelDao;

    @Autowired
    private UserMao userMao;

    @Autowired
    private VideoStatMao videoStatMao;

    @Autowired
    private UserFollowMao userFollowMao;

    @Autowired
    private TpsClient tpsClient;

    @Autowired
    private EventClient eventClient;

    @Autowired
    private VideoReportDao videoReportDao;

    @Autowired
    private VideoLikeEao videoLikeEao;

    @Autowired
    private VideoCommentDao videoCommentDao;

    @Autowired
    private VideoCommentLikeDao videoCommentLikeDao;

    @Autowired
    private VideoHotDefDao videoHotDefDao;

    @Autowired
    private VideoHotInstDao videoHotInstDao;

    @Autowired
    private AcctDao acctDao;

    @Autowired
    private AcctLogEao acctLogEao;

    @Autowired
    private UserVideoMao userVideoMao;

    @Autowired
    private UserExtDao userExtDao;

    @Autowired
    private VideoViewStatMao videoViewStatMao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserAttentionDao userAttentionDao;

    @Override
    public Long addVideo(Long userId, String title, String href, String thumb, String vodId, String lat, String lng) {
        AtomicReference<Long> videoId = null;
        Db.tx(() -> {
            userExtDao.incProductionsNum(userId, 1);
            videoId.set(videoDao.add(userId, title, href, thumb, vodId, lat, lng, getCity(lat, lng)));
            return true;
        });

        return videoId.get();
    }

    @Override
    public Page<VideoVo> pageByUserId(Long userId, String audit, int pageNumber, int pageSize) {
        Page<CmfUserVideo> page = videoDao.pageByUserId(userId, audit, pageNumber, pageSize);

        List<VideoVo> list = ((Converter<List<CmfUserVideo>, List<VideoVo>>) videos -> {
            List<VideoVo> vos = new ArrayList<>();
            videos.forEach((v) -> {
                VideoVo vo = new VideoVo();
//                vo.setId(v.getVideoId());
//                vo.setTitle(v.getTitle());
//                vo.setHref(v.getHref());
//                vo.setThumb(v.getThum());
//                vo.setComments(v.getComments());
//                VideoStatMo stat = videoStatMao.findByVideoId(v.getVideoId());
//
//                vo.setLikes(stat == null ? 0 : stat.getLikes());
//                vo.setViews(stat == null ? 0 : stat.getViews());
//                vo.setComments(stat == null ? 0 : stat.getComments());
//                vo.setShares(stat == null ? 0 : stat.getShares());
//
//                if (null != userId) {
//                    vo.setFollow(userFollowMao.exists(userId, v.getUserId()) ? "1" : "0");
//                    vo.setLike(userVideoMao.existsLike(v.getVideoId(), userId) ? "1" : "0");
//                } else {
//                    vo.setFollow("0");
//                    vo.setLike("0");
//                }
//
//                vo.setAudit(v.getAuditStatus());
                vos.add(vo);
            });
            return vos;
        }).convert(page.getList());

        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<FocusVideoVo> pageFocus(Long userId, int pageNumber, int pageSize) {
        Long[] follwers = listFollwer(userId);

        // 没有关注者
        if (follwers == null || follwers.length == 0) {
            return new Page();
        }

        Page<VideoEo> page = videoEao.pageByUserIds(pageNumber, pageSize, follwers);
        List<FocusVideoVo> list = ((Converter<List<VideoEo>, List<FocusVideoVo>>) videos -> {
            List<FocusVideoVo> vos = new ArrayList<>();

            if (videos != null) {
                for (VideoEo video : videos) {
                    FocusVideoVo vo = new FocusVideoVo();

//                    UserMo userMo = userMao.findByUserId(video.getUserId());
//                    vo.setVedioId(video.getVedioId());
//                    vo.setUserId(video.getUserId());
//                    vo.setNickName(userMo.getNickName());
//                    vo.setAvatar(userMo.getAvatar());
//                    vo.setLive(userMo.getLive());
//
//                    vo.setVedioId(video.getVedioId());
//                    vo.setTitle(video.getTitle());
//                    vo.setMedia(video.getMedia());
//                    vo.setCover(video.getCover());
//
//                    VideoStatMo stat = videoStatMao.findByVideoId(video.getVedioId());
//
//                    vo.setLikes(stat == null ? 0 : stat.getLikes());
//                    vo.setViews(stat == null ? 0 : stat.getViews());
//                    vo.setComments(stat == null ? 0 : stat.getComments());
//                    vo.setShares(stat == null ? 0 : stat.getShares());
//
//                    if (null != userId) {
//                        vo.setFollow(userFollowMao.exists(userId, video.getUserId()) ? "1" : "0");
//                        vo.setLike(userVideoMao.existsLike(video.getVedioId(), userId) ? "1" : "0");
//                    } else {
//                        vo.setFollow("0");
//                        vo.setLike("0");
//                    }
//
//                    try {
//                        vo.setCreateTime(DateUtil.parse(video.getCreateTime()));
//                    } catch (ParseException e) {
//                        // ignore ...
//                    }
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<ScityVideoVo> pageScity(Long userId, String lat, String lng, int pageNumber, int pageSize) {
        Address address = tpsClient.getAddress(lat, lng);
        if (address == null) {
            return new Page<>(null, pageNumber, pageSize, 0, 0);
        }

        Page<VideoEo> page = videoEao.pageByCity(pageNumber, pageSize, address.getCity(), lat, lng);
        List<ScityVideoVo> list = ((Converter<List<VideoEo>, List<ScityVideoVo>>) videos -> {
            List<ScityVideoVo> vos = new ArrayList<>();

            if (videos != null) {
                for (VideoEo video : videos) {
//                    ScityVideoVo vo = new ScityVideoVo();
//
//                    UserMo userMo = userMao.findByUserId(video.getUserId());
//
//                    vo.setUserId(video.getUserId());
//                    vo.setNickName(userMo.getNickName());
//                    vo.setAvatar(userMo.getAvatar());
//                    vo.setLive(userMo.getLive());
//
//                    vo.setVedioId(video.getVedioId());
//                    vo.setTitle(video.getTitle());
//                    vo.setMedia(video.getMedia());
//                    vo.setCover(video.getCover());
//                    vo.setDistance(
//                            GeoUtil.distance(
//                                    Double.valueOf(lat),
//                                    Double.valueOf(lng),
//                                    GeoUtil.getLat(video.getLoc()),
////                                    GeoUtil.getLng(video.getLoc()))
//                    );
//
//                    if (null != userId) {
//                        vo.setFollow(userFollowMao.exists(userId, video.getUserId()) ? "1" : "0");
//                        vo.setLike(userVideoMao.existsLike(video.getVedioId(), userId) ? "1" : "0");
//                    } else {
//                        vo.setFollow("0");
//                        vo.setLike("0");
//                    }
//
//                    try {
//                        vo.setCreateTime(DateUtil.parse(video.getCreateTime()));
//                    } catch (ParseException e) {
//                        // ignore ...
//                    }
//                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<FoundVideoVo> pageFound(Long userId, int pageNumber, int pageSize) {
        Page<VideoEo> page = videoEao.pageByFound(pageNumber, pageSize);
        List<FoundVideoVo> list = ((Converter<List<VideoEo>, List<FoundVideoVo>>) videos -> {
            List<FoundVideoVo> vos = new ArrayList<>();

            if (videos != null) {
                for (VideoEo video : videos) {
                    FoundVideoVo vo = new FoundVideoVo();

//                    UserMo userMo = userMao.findByUserId(video.getUserId());
//
//                    vo.setUserId(video.getUserId());
//                    vo.setNickName(userMo.getNickName());
//                    vo.setAvatar(userMo.getAvatar());
//
//                    vo.setVedioId(video.getVedioId());
//                    vo.setTitle(video.getTitle());
//                    vo.setMedia(video.getMedia());
//                    vo.setCover(video.getCover());

//                    VideoStatMo stat = videoStatMao.findByVideoId(video.getVedioId());
//
//                    vo.setLikes(stat == null ? 0 : stat.getLikes());
//                    vo.setViews(stat == null ? 0 : stat.getViews());
//                    vo.setComments(stat == null ? 0 : stat.getComments());
//                    vo.setShares(stat == null ? 0 : stat.getShares());
//                    if (null != userId) {
//                        vo.setFollow(userFollowMao.exists(userId, video.getUserId()) ? "1" : "0");
//                        vo.setLike(userVideoMao.existsLike(video.getVedioId(), userId) ? "1" : "0");
//                    } else {
//                        vo.setFollow("0");
//                        vo.setLike("0");
//                    }
//                    try {
//                        vo.setCreateTime(DateUtil.parse(video.getCreateTime()));
//                    } catch (ParseException e) {
//                        // ignore ...
//                    }
//                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<FocusVideoByPhpVo> pageFocusByPhp(Long userId, int pageNumber, int pageSize) {
        List<Long> attentionIds = userAttentionDao.listByUid(userId);
        if (null == attentionIds){
            return new Page<>();
        }
        Page<VideoEo> page = videoEao.pageByUserIds(pageNumber, pageSize, attentionIds.toArray(new Long[attentionIds.size()]));
        List<FocusVideoByPhpVo> list = ((Converter<List<VideoEo>, List<FocusVideoByPhpVo>>) videos -> {
            List<FocusVideoByPhpVo> vos = new ArrayList<>();
            if (videos != null) {
                for (VideoEo video : videos) {
                    FocusVideoByPhpVo vo = new FocusVideoByPhpVo();

                    vo.setId(video.getVedioId());
                    vo.setVideo_id(video.getVodId());
                    vo.setUid(video.getUserId());
                    vo.setTitle(video.getTitle());
                    vo.setThumb(video.getCover());
                    vo.setThumb_s(video.getCover());
                    vo.setHref(video.getMedia());
                    vo.setHref_w(video.getMedia());

                    VideoStatMo videoStatMo = videoStatMao.findByVideoId(video.getVedioId());

                    if (null != videoStatMo) {
                        vo.setLikes(videoStatMo == null ? 0 : videoStatMo.getLikes());
                        vo.setViews(videoStatMo == null ? 0 : videoStatMo.getViews());
                        vo.setComments(videoStatMo == null ? 0 : videoStatMo.getComments());
                        vo.setShares(videoStatMo == null ? 0 : videoStatMo.getShares());
                    }
                    vo.setSteps(0);

                    vo.setAddtime(video.getCreateTime());
                    if (StringUtil.isNotEmpty(video.getLoc()) && video.getLoc().split(",").length > 1) {
                        vo.setLat(video.getLoc().split(",")[0]);
                        vo.setLng(video.getLoc().split(",")[1]);
                    }

                    vo.setCity(video.getCity());
                    vo.setStatus("1");
                    vo.setMusic_id(video.getMusicId());
                    vo.setXiajia_reason("");
                    vo.setNopass_time("0");
                    vo.setWatch_ok("0");
                    vo.setIs_ad("0");
                    vo.setAd_url("");
                    vo.setLabelid("0");
                    vo.setIsgoods("0");
                    vo.setIspay("0");
                    vo.setP_nums("0");
                    vo.setP_expire("0");
                    vo.setP_add("0");
                    vo.setClassid("0");
                    vo.setCoin("0");
                    vo.setGoodsid("0");
                    vo.setAnyway(video.getAnyway());
                    try {
                        vo.setDatetime(TimeUtil.getDatetimeStr(DateUtil.parse(video.getCreateTime())));
                        vo.setAddtime_format(String.valueOf(DateUtil.parse(video.getCreateTime()).getTime() / 1000));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    //音乐信息
                    MusicByPhpVo musicinfo = new MusicByPhpVo();
                    if (null != video.getMusicId()) {
                        musicinfo.setId(video.getMusicId());
                        musicinfo.setTitle(video.getMusicTitle());
                        musicinfo.setAuthor(video.getMusicAuthor());
                        musicinfo.setImg_url(video.getMusicImgUrl());
                        musicinfo.setLength(video.getMusicLength());
                        musicinfo.setFile_url(video.getMusicFileUrl());
                        musicinfo.setUse_nums(0);
                        musicinfo.setMusic_format(video.getMusicTitle());
                    }
                    vo.setMusicinfo(musicinfo);
                    vo.setLabel_name("");
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<ScityVideoByPhpVo> pageScityByPhp(String city, String lat, String lng, int pageNumber, int pageSize) {
        Page<VideoEo> page = videoEao.pageByCity(pageNumber, pageSize, city, lat, lng);
        List<ScityVideoByPhpVo> list = ((Converter<List<VideoEo>, List<ScityVideoByPhpVo>>) videos -> {
            List<ScityVideoByPhpVo> vos = new ArrayList<>();
            if (videos != null) {
                for (VideoEo video : videos) {
                    ScityVideoByPhpVo vo = new ScityVideoByPhpVo();

                    vo.setId(video.getVedioId());
                    vo.setVideo_id(video.getVodId());
                    vo.setUid(video.getUserId());
                    vo.setTitle(video.getTitle());
                    vo.setThumb(video.getCover());
                    vo.setThumb_s(video.getCover());
                    vo.setHref(video.getMedia());
                    vo.setHref_w(video.getMedia());

                    VideoStatMo videoStatMo = videoStatMao.findByVideoId(video.getVedioId());

                    if (null != videoStatMo) {
                        vo.setLikes(videoStatMo == null ? 0 : videoStatMo.getLikes());
                        vo.setViews(videoStatMo == null ? 0 : videoStatMo.getViews());
                        vo.setComments(videoStatMo == null ? 0 : videoStatMo.getComments());
                        vo.setShares(videoStatMo == null ? 0 : videoStatMo.getShares());
                    }
                    vo.setSteps(0);

                    vo.setAddtime(video.getCreateTime());
                    if (StringUtil.isNotEmpty(video.getLoc()) && video.getLoc().split(",").length > 1) {
                        vo.setLat(video.getLoc().split(",")[0]);
                        vo.setLng(video.getLoc().split(",")[1]);
                    }

                    vo.setDistance(
                            GeoUtil.distance(
                                    Double.valueOf(lat),
                                    Double.valueOf(lng),
                                    GeoUtil.getLat(video.getLoc()),
                                    GeoUtil.getLng(video.getLoc()))
                            );

                    vo.setCity(video.getCity());
                    vo.setStatus("1");
                    vo.setMusic_id(video.getMusicId());
                    vo.setXiajia_reason("");
                    vo.setNopass_time("0");
                    vo.setWatch_ok("0");
                    vo.setIs_ad("0");
                    vo.setAd_url("");
                    vo.setLabelid("0");
                    vo.setIsgoods("0");
                    vo.setIspay("0");
                    vo.setP_nums("0");
                    vo.setP_expire("0");
                    vo.setP_add("0");
                    vo.setClassid("0");
                    vo.setCoin("0");
                    vo.setGoodsid("0");
                    vo.setAnyway(video.getAnyway());
                    try {
                        vo.setDatetime(TimeUtil.getDatetimeStr(DateUtil.parse(video.getCreateTime())));
                        vo.setAddtime_format(String.valueOf(DateUtil.parse(video.getCreateTime()).getTime() / 1000));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    //音乐信息
                    MusicByPhpVo musicinfo = new MusicByPhpVo();
                    if (null != video.getMusicId()) {
                        musicinfo.setId(video.getMusicId());
                        musicinfo.setTitle(video.getMusicTitle());
                        musicinfo.setAuthor(video.getMusicAuthor());
                        musicinfo.setImg_url(video.getMusicImgUrl());
                        musicinfo.setLength(video.getMusicLength());
                        musicinfo.setFile_url(video.getMusicFileUrl());
                        musicinfo.setUse_nums(0);
                        musicinfo.setMusic_format(video.getMusicTitle());
                    }
                    vo.setMusicinfo(musicinfo);
                    vo.setLabel_name("");
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }


    @Override
    public Page<FoundVideoByPhpVo> pageFoundByPhp(Long userId, int pageNumber, int pageSize) {
        Page<VideoEo> page = videoEao.pageByFound(pageNumber, pageSize);
        List<FoundVideoByPhpVo> list = ((Converter<List<VideoEo>, List<FoundVideoByPhpVo>>) videos -> {
            List<FoundVideoByPhpVo> vos = new ArrayList<>();

            if (videos != null) {
                for (VideoEo video : videos) {
                    FoundVideoByPhpVo vo = new FoundVideoByPhpVo();

                    vo.setId(video.getVedioId());
                    vo.setVideo_id(video.getVodId());
                    vo.setUid(video.getUserId());
                    vo.setTitle(video.getTitle());
                    vo.setThumb(video.getCover());
                    vo.setThumb_s(video.getCover());
                    vo.setHref(video.getMedia());
                    vo.setHref_w(video.getMedia());

                    VideoStatMo videoStatMo = videoStatMao.findByVideoId(video.getVedioId());

                    if (null != videoStatMo) {
                        vo.setLikes(videoStatMo == null ? 0 : videoStatMo.getLikes());
                        vo.setViews(videoStatMo == null ? 0 : videoStatMo.getViews());
                        vo.setComments(videoStatMo == null ? 0 : videoStatMo.getComments());
                        vo.setShares(videoStatMo == null ? 0 : videoStatMo.getShares());
                    }
                    vo.setSteps(0);

                    vo.setAddtime(video.getCreateTime());
                    if (StringUtil.isNotEmpty(video.getLoc()) && video.getLoc().split(",").length > 1) {
                        vo.setLat(video.getLoc().split(",")[0]);
                        vo.setLng(video.getLoc().split(",")[1]);
                    }

                    vo.setCity(video.getCity());
                    vo.setStatus("1");
                    vo.setMusic_id(video.getMusicId());
                    vo.setXiajia_reason("");
                    vo.setNopass_time("0");
                    vo.setWatch_ok("0");
                    vo.setIs_ad("0");
                    vo.setAd_url("");
                    vo.setLabelid("0");
                    vo.setIsgoods("0");
                    vo.setIspay("0");
                    vo.setP_nums("0");
                    vo.setP_expire("0");
                    vo.setP_add("0");
                    vo.setClassid("0");
                    vo.setCoin("0");
                    vo.setGoodsid("0");
                    vo.setAnyway(video.getAnyway());
                    try {
                        vo.setDatetime(TimeUtil.getDatetimeStr(DateUtil.parse(video.getCreateTime())));
                        vo.setAddtime_format(String.valueOf(DateUtil.parse(video.getCreateTime()).getTime() / 1000));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    //音乐信息
                    MusicByPhpVo musicinfo = new MusicByPhpVo();
                    if (null != video.getMusicId()) {
                        musicinfo.setId(video.getMusicId());
                        musicinfo.setTitle(video.getMusicTitle());
                        musicinfo.setAuthor(video.getMusicAuthor());
                        musicinfo.setImg_url(video.getMusicImgUrl());
                        musicinfo.setLength(video.getMusicLength());
                        musicinfo.setFile_url(video.getMusicFileUrl());
                        musicinfo.setUse_nums(0);
                        musicinfo.setMusic_format(video.getMusicTitle());
                    }
                    vo.setMusicinfo(musicinfo);
                    vo.setLabel_name("");
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }


    @Override
    public Page<HotVideoVo> pageHot(Long userId, int pageNumber, int pageSize) {
        Page<CmfUserVideo> page = videoDao.pageByHot("2", pageNumber, pageSize);
        List<HotVideoVo> list = ((Converter<List<CmfUserVideo>, List<HotVideoVo>>) videos -> {
            List<HotVideoVo> vos = new ArrayList<>();

            if (videos != null) {
                for (CmfUserVideo video : videos) {
                    HotVideoVo vo = new HotVideoVo();

//                    UserMo userMo = userMao.findByUserId(video.getUserId());
//
//                    if (userMo != null) {
//                        vo.setUserId(video.getUserId());
//                        vo.setNickName(userMo.getNickName());
//                        vo.setAvatar(userMo.getAvatar());
//                        vo.setLive(userMo.getLive());
//                    }
//                    vo.setVideoId(video.getVideoId());
//                    vo.setTitle(video.getTitle());
//                    vo.setMedia(video.getHref());
//                    vo.setCover(video.getThum());
//
//                    VideoStatMo stat = videoStatMao.findByVideoId(video.getVideoId());
//
//                    vo.setLikes(stat == null ? 0 : stat.getLikes());
//                    vo.setViews(stat == null ? 0 : stat.getViews());
//                    vo.setComments(stat == null ? 0 : stat.getComments());
//                    vo.setShares(stat == null ? 0 : stat.getShares());
//                    if (null != userId) {
//                        vo.setFollow(userFollowMao.exists(userId, video.getUserId()) ? "1" : "0");
//                        vo.setLike(userVideoMao.existsLike(video.getVideoId(), userId) ? "1" : "0");
//                    } else {
//                        vo.setFollow("0");
//                        vo.setLike("0");
//                    }
//                    vo.setCreateTime(video.getCreateTime());

                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Long addVideoByLocal(Long userId, String title, String media, String cover, String lat, String lng) {
        UploadVod uploadVod = tpsClient.uploadVod(media, cover);
        if (null == uploadVod) {
            BizUtil.exception("上传视频失败");
        }

        return videoDao.add(userId, title, uploadVod.getMediaUrl(), uploadVod.getCoverUrl(), uploadVod.getFileId(), lat, lng, getCity(lat, lng));
    }

    @Override
    public VideoStatVo getStat(Long videoId, Long userId) {
//        CmfUserVideo video = videoDao.findById(videoId);
//        if (video == null) {
//            return null;
//        }

        VideoStatVo statVo = new VideoStatVo();
        statVo.setVideoId(videoId);
        // 关注信息
        if (userId != null) {
            statVo.setFollow(userFollowMao.exists(userId, videoId) ? "1" : "0");
            statVo.setLike(userVideoMao.existsLike(videoId, userId) ? "1" : "0");
        } else {
            statVo.setFollow("0");
            statVo.setLike("0");
        }

        // 统计信息
        VideoStatMo videoStatMo = videoStatMao.findByVideoId(videoId);
//        UserMo userMo = userMao.findByUserId(video.getUserId());
//        if (null != userMo) {
//            statVo.setAvatar(userMo.getAvatar());
//            statVo.setUserId(userMo.getUserId());
//            statVo.setLive(userMo.getLive());
//        }
//
//        statVo.setHref(video.getHref());
//        statVo.setThumb(video.getThum());
//        statVo.setTitle(video.getTitle());
//
//        statVo.setLikes(videoStatMo == null ? 0 : videoStatMo.getLikes());
//        statVo.setComments(videoStatMo == null ? 0 : videoStatMo.getComments());
//        statVo.setViews(videoStatMo == null ? 0 : videoStatMo.getViews());
//        statVo.setShares(videoStatMo == null ? 0 : videoStatMo.getShares());

        return statVo;
    }


    @Override
    public VideoStatNumVo getStatNum(Long videoId) {
        VideoStatNumVo statVo = new VideoStatNumVo();
        statVo.setVideoId(videoId);

        // 统计信息
        VideoStatMo videoStatMo = videoStatMao.findByVideoId(videoId);

        statVo.setLikes(videoStatMo == null ? 0 : videoStatMo.getLikes());
        statVo.setComments(videoStatMo == null ? 0 : videoStatMo.getComments());
        statVo.setViews(videoStatMo == null ? 0 : videoStatMo.getViews());
        statVo.setShares(videoStatMo == null ? 0 : videoStatMo.getShares());

        return statVo;
    }

    @Override
    public void like(Long userId, Long videoId) {
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("videoId", videoId);
        param.put("likeTime", System.currentTimeMillis());
        eventClient.fireEvent(Const.EVENT_TOPIC_LIKE_VIDEO, JSON.toJSONString(param));
        // 更新统计数据
        userExtDao.incLikesNum(userId, 1);
    }

    @Override
    public void cancelLike(Long userId, Long videoId) {
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("videoId", videoId);
        eventClient.fireEvent(Const.EVENT_TOPIC_CANCEL_LIKE_VIDEO, JSON.toJSONString(param));
        // 更新统计数据
        userExtDao.decLikesNum(userId, 1);
    }

    @Override
    public void report(Long userId, Long videoId) {
        videoStatMao.incShares(videoId);
//        CmfUserVideo userVideo = videoDao.findById(videoId);
//        videoReportDao.save(userId, userVideo.getUserId(), videoId);
    }

    @Override
    public void download(Long userId, Long videoId) {
        videoStatMao.incShares(videoId);
    }

    @Override
    public Page<LikeVideoVo> pageVideoLike(Long userId, Integer pageNumber, Integer pageSize) {
        Page<VideoLikeEo> page = videoLikeEao.pageByUserId(pageNumber, pageSize, userId);
        List<LikeVideoVo> list = ((Converter<List<VideoLikeEo>, List<LikeVideoVo>>) videos -> {
            List<LikeVideoVo> vos = new ArrayList<>();

            if (videos != null) {
                for (VideoLikeEo video : videos) {
                    LikeVideoVo vo = new LikeVideoVo();

                    UserMo userMo = userMao.findByUserId(video.getUserId());

                    vo.setUserId(video.getUserId());
                    vo.setNickName(userMo.getNickName());
                    vo.setAvatar(userMo.getAvatar());
                    vo.setLive(userMo.getLive());

                    vo.setVedioId(video.getVideoId());
                    vo.setTitle(video.getTitle());
                    vo.setHref(video.getMedia());
                    vo.setThumb(video.getCover());

                    VideoStatMo stat = videoStatMao.findByVideoId(video.getVideoId());

                    vo.setLikes(stat == null ? 0 : stat.getLikes());
                    vo.setViews(stat == null ? 0 : stat.getViews());
                    vo.setComments(stat == null ? 0 : stat.getComments());
                    vo.setShares(stat == null ? 0 : stat.getShares());

                    vo.setLike(userVideoMao.existsLike(video.getVideoId(), userId) ? "1" : "0");
                    vo.setFollow(userFollowMao.exists(userId, video.getVideoUserId()) ? "1" : "0");

                    try {
                        vo.setLikeTime(DateUtil.parse(video.getLikeTime()));
                    } catch (ParseException e) {
                        // ignore ...
                    }
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public void viewTimeVideo(Long userId, Long videoId, Integer timeLong) {

        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("videoId", videoId);
        param.put("timeLong", timeLong);
        eventClient.fireEvent(Const.EVENT_TOPIC_VIEW_VIDEO_TIME, JSON.toJSONString(param));
//        //每日任务 时长统计
//        String viewDay = DateUtil.formatDate(new Date());
//        VideoViewStatMo videoViewStatMo = videoViewStatMao.findByUserId(userId);
//        //不同新建
//        if (videoViewStatMo == null) {
//            VideoViewStatMo vi = new VideoViewStatMo();
//            vi.setUserId(userId);
//            vi.setViewDayTime(timeLong);
//            vi.setViewDay(viewDay);
//            vi.setViewTotalTime(timeLong);
//            videoViewStatMao.save(vi);
//        } else {
//            VideoViewStatMo vi = new VideoViewStatMo();
//            vi.setUserId(userId);
//            if (viewDay.equals(videoViewStatMo.getViewDay())) { //日期相同相加
//                vi.setViewDay(viewDay);
//                vi.setViewDayTime(videoViewStatMo.getViewDayTime() + timeLong);
//                vi.setViewTotalTime(videoViewStatMo.getViewTotalTime() + timeLong);
//                vi.setViewDay(viewDay);
//            } else {
//                vi.setViewDayTime(timeLong);
//                vi.setViewDay(viewDay);
//                vi.setViewTotalTime(videoViewStatMo.getViewTotalTime() + timeLong);
//            }
//            videoViewStatMao.update(vi);
//        }
    }

    @Override
    public Long addComment(Long userId, Long videoId, Long replyCommentId, String content) {
        Long commentId = null;
        if (null == replyCommentId) {
            commentId = videoCommentDao.add(userId, content, videoId);
        } else {
            CmfVideoComment videoComment = videoCommentDao.findById(replyCommentId);

            //判断回复的评论类型
            if (CmfVideoComment.TYPE_COMMENT.equals(videoComment.getType())) {
                commentId = videoCommentDao.add(userId, content, videoId, replyCommentId,
                        videoComment.getCommentId(), CmfVideoComment.TYPE_REPLY, videoComment.getUserId());
                videoCommentDao.incReplys(videoComment.getCommentId());


            } else {
                commentId = videoCommentDao.add(userId, content, videoId, replyCommentId,
                        videoComment.getParentCommentId(), CmfVideoComment.TYPE_REPLY_TOO, videoComment.getUserId());
                videoCommentDao.incReplys(videoComment.getParentCommentId());
            }
        }

        return commentId;
    }

    @Override
    public Long likeComment(Long userId, Long commentId) {
        videoCommentDao.incLikes(commentId);
        CmfVideoComment cmfVideoComment = videoCommentDao.findById(commentId);
        videoCommentLikeDao.save(userId, commentId, cmfVideoComment.getVideoId());
        return commentId;
    }

    @Override
    public Page<VideoCommentVo> pageVideoComment(Long videoId, Integer pageNumber, Integer pageSize) {
        Page<CmfVideoComment> page = videoCommentDao.pageByComment(videoId, pageNumber, pageSize);
        List<VideoCommentVo> list = convertComment(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Page<VideoCommentVo> pageCommentReply(Long commentId, Integer pageNumber, Integer pageSize) {
        if (commentId.longValue() == 0L) {
            return new Page<>();
        }
        Page<CmfVideoComment> page = videoCommentDao.pageByReply(commentId, pageNumber, pageSize);
        List<VideoCommentVo> list = convertComment(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }


    @Override
    public Page<VideoCommentVo> pageCommentByUserId(Long userId, Integer pageNumber, Integer pageSize) {
        Page<CmfVideoComment> page = videoCommentDao.pageByUserId(userId, pageNumber, pageSize);
        List<VideoCommentVo> list = convertComment(page.getList());
        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public List<VideoHotDefVo> listHotDef() {
        List<CmfVideoHotDef> hotDefs = videoHotDefDao.list();
        List<VideoHotDefVo> list = ((Converter<List<CmfVideoHotDef>, List<VideoHotDefVo>>) hotDefList -> {
            List<VideoHotDefVo> vos = new ArrayList<>();

            if (hotDefList != null) {
                for (CmfVideoHotDef hotDef : hotDefList) {
                    VideoHotDefVo vo = new VideoHotDefVo();
                    vo.setHotId(hotDef.getHotId());
                    vo.setHotName(hotDef.getHotName());
                    vo.setHotOprCode(hotDef.getHotOprCode());
                    vo.setHotOprName(hotDef.getHotOprName());
                    vo.setHotTime(hotDef.getHotTime());
                    vo.setHotValue(hotDef.getHotValue());
                    vo.setPrice(hotDef.getPrice());
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(hotDefs);

        return list;
    }

    @Override
    public UploadSigVo getUploadSigVo() {
        return tpsClient.getUploadSig();
    }

    @Override
    public void buyHot(Long userId, Long videoId, Long hotId, String pwd) {
        User user = userDao.getById(userId);
        if (StringUtil.isEmpty(user.getTradePwd())) {
            BizUtil.exception("您还未设置交易密码");
        }
        if (StringUtil.isEmpty(pwd)) {
            BizUtil.exception("请输入密码");
        }
        if (!AesUtil.encode(pwd).equals(user.getTradePwd())) {
            BizUtil.exception("交易密码错误");
        }
        CmfVideoHotDef hotDef = videoHotDefDao.findById(hotId);
        Acct acct = acctDao.queryGAcct(userId);
        if (acct.getBalanceFee().compareTo(hotDef.getPrice()) < 0) {
            BizUtil.exception("果子余额不足");
        }

        Db.tx(() -> {
            Date startTime = new Date();
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(startTime);
            endCalendar.add(Calendar.HOUR_OF_DAY, hotDef.getHotTime());
            Long instId = videoHotInstDao.save(hotDef.getHotId(), hotDef.getHotValue(),
                    videoId, hotDef.getPrice(), hotDef.getHotTime(), hotDef.getHotOprCode(), startTime, endCalendar.getTime());

            //扣减果子余额
            acctDao.minusGBalance(userId, hotDef.getPrice(), instId.toString(),
                    AcctTradeType.BUY_VIDEO_HOT, BusiType.BUY_VIDEO_HOT);

            //记录es日志
            acctLogEao.save(UuidUtil.get(), acct.getAcctId(), userId, AcctType.ACCT_TYPE_G, hotDef.getPrice(),
                    Acct.FEE_IN_DE_MINUS, instId.toString(), AcctTradeType.BUY_VIDEO_HOT, AcctTradeType.BUY_VIDEO_HOT_NAME,
                    BusiType.BUY_VIDEO_HOT, new Date());

            //先直接增加曝光数
            videoStatMao.incViews(videoId, hotDef.getHotValue());

            return true;
        });
    }

    @Override
    public CmfVideoComment getCommentByCid(Long commentId) {
        return videoCommentDao.findById(commentId);
    }

//    @Override
//    public CmfUserVideo getVideoByVid(Long videoId) {
//        return videoDao.findById(videoId);
//    }

    @Override
    public Page<SearchVideoVo> searchVideo(Long userId, String key, Integer pageNumber, Integer pageSize) {
        Map<String, Object> param = new HashMap<>();
        param.put("key", key);
        param.put("auditStatus", CmfUserVideo.AUDIT_STATUS_PASS);

        Page<CmfUserVideo> page = videoDao.searchVideo(param, pageNumber, pageSize);

        List<SearchVideoVo> list = ((Converter<List<CmfUserVideo>, List<SearchVideoVo>>) videos -> {
            List<SearchVideoVo> vos = new ArrayList<>();

            videos.forEach((v) -> {
                SearchVideoVo vo = new SearchVideoVo();

//                UserMo userMo = userMao.findByUserId(v.getUserId());
//                vo.setVideoId(v.getVideoId());
//                vo.setUserId(v.getUserId());
//                vo.setNickName(userMo.getNickName());
//                vo.setAvatar(userMo.getAvatar());
//                vo.setLive(userMo.getLive());
//
//                vo.setVideoId(v.getVideoId());
//                vo.setTitle(v.getTitle());
//                vo.setMedia(v.getHref());
//                vo.setCover(v.getThum());
//
//                VideoStatMo stat = videoStatMao.findByVideoId(v.getVideoId());
//
//                vo.setLikes(stat == null ? 0 : stat.getLikes());
//                vo.setViews(stat == null ? 0 : stat.getViews());
//                vo.setComments(stat == null ? 0 : stat.getComments());
//                vo.setShares(stat == null ? 0 : stat.getShares());
//
//
//                vo.setLike(userVideoMao.existsLike(v.getVideoId(), userId) ? "1" : "0");
//                vo.setFollow(userFollowMao.exists(userId, v.getUserId()) ? "1" : "0");
//
//                vo.setCreateTime(v.getCreateTime());

                vos.add(vo);
            });
            return vos;
        }).convert(page.getList());

        return new Page<>(list, pageNumber, pageSize, page.getTotalPage(), page.getTotalRow());
    }

    @Override
    public Integer action(Long videoId, String action, Long userId) {
        if ("1".equals(action)) {
            videoStatMao.incLikes(videoId);
            VideoStatMo videoStatMo = videoStatMao.findByVideoId(videoId);
            if (null != userId){
                userMao.incLikes(userId);
            }
            return videoStatMo.getLikes();
        } else if ("2".equals(action)) {
            videoStatMao.decLikes(videoId);
            if (null != userId){
                userMao.decLikes(userId);
            }
            VideoStatMo videoStatMo = videoStatMao.findByVideoId(videoId);
            return videoStatMo.getLikes();
        } else {
            Map<String, Object> param = new HashMap<>();
            param.put("videoId", videoId);
            param.put("action", action);
            param.put("userId", userId);
            param.put("actionTime", System.currentTimeMillis());
            eventClient.fireEvent(Const.EVENT_TOPIC_VIDEO_ACTION, JSON.toJSONString(param));
        }
        return 0;
    }

    private List<VideoCommentVo> convertComment(List<CmfVideoComment> cmfVideoComments) {
        return ((Converter<List<CmfVideoComment>, List<VideoCommentVo>>) comments -> {
            List<VideoCommentVo> vos = new ArrayList<>();

            if (comments != null) {
                for (CmfVideoComment comment : comments) {
                    VideoCommentVo vo = new VideoCommentVo();

                    UserMo userMo = userMao.findByUserId(comment.getUserId());

                    vo.setUserId(userMo.getUserId());
                    vo.setNickName(userMo.getNickName());
                    vo.setAvatar(userMo.getAvatar());

                    vo.setVideoId(comment.getCommentId());
                    vo.setCommentId(comment.getCommentId());
                    vo.setLikes(comment.getLikes());
                    vo.setReplys(comment.getReplys());
                    vo.setType(comment.getType());
                    vo.setContent(comment.getContent());
                    vo.setReplyCommentId(comment.getReplyCommentId());

                    if (null != comment.getToUserId() && comment.getToUserId().longValue() != 0L) {
                        userMo = userMao.findByUserId(comment.getUserId());
                        vo.setToUserId(userMo.getUserId());
                        vo.setToNickName(userMo.getNickName());
                    }
                    try {
                        vo.setCreateTime(DateUtil.format(comment.getCreateTime()));
                    } catch (Exception e) {
                        // ignore ...
                    }
                    vos.add(vo);
                }
            }
            return vos;
        }).convert(cmfVideoComments);
    }

    // SECTION : INNER HELPER

    private String getCity(String lat, String lng) {
        Address address = tpsClient.getAddress(lat, lng);
        return address == null ? "未知" : address.getCity();
    }

    private Long[] listFollwer(Long userId) {
        List<Long> list = new ArrayList<>();
        List<UserRel> rels = userRelDao.listFollow(userId);
        for (UserRel rel : rels) {
            list.add(rel.getRelUserId());
        }
        return list.toArray(new Long[list.size()]);
    }

}
